/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wumpusworld;

import java.awt.AlphaComposite;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.net.URL;

/**
 *
 * @author Jedrek
 */
public class MyCanvas extends Canvas{

    public static final int HIDDEN = 1;
    public static final int PIT = 2;
    public static final int WIND = 4;
    public static final int SULFUR = 8;
    public static final int WUMPUS = 16;
    public static final int GOLD = 32;
    public static final int ENTERENCE_LEFT = 64;
    public static final int ENTERENCE_RIGHT = 128;
    public static final int ENTERENCE_UP = 256;
    public static final int ENTERENCE_DOWN = 512;
    public static final int CHEST = 1024;

    /**
     * map to be drawn
     */
    int[][] map;

    /**
     * images
     */
    Image imgBlueDragon;
    Image imgGreenDragon;
    Image imgBronzeDragon;
    Image imgPit;
    Image imgSulfur;
    Image imgWind;
    Image imgGold;
    Image imgUnknown;
    Image imgKnight;
    Image imgChest;

    /**
     * whether to show what is in hidden fields or not
     */
    boolean revealHidden = false;
    
    public boolean drawAgent = false;
    public Point agentPosition = null;

    public static boolean showHints = false;
    boolean doPrintHints = false;
    float noteW,noteP;
    int posX,posY;
    
    public MyCanvas(){
        super();

        map = null;

        //loading images
        URL url = Main.class.getResource("wampus/blue-dragon.jpg");
        imgBlueDragon = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/Green-dragon.jpg");
        imgGreenDragon = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/bronze-dragon.jpg");
        imgBronzeDragon = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/pit.jpg");
        imgPit = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/sulfur.jpg");
        imgSulfur = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/wind.jpg");
        imgWind = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/goldbars.jpg");
        imgGold = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/unknown.jpg");
        imgUnknown = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/knight.jpg");
        imgKnight = Toolkit.getDefaultToolkit().getImage(url);
        url = Main.class.getResource("wampus/chest.jpg");
        imgChest = Toolkit.getDefaultToolkit().getImage(url);

        
    }

    /**
     * painting map
     * @param g
     */
    @Override
    public void paint(Graphics g){
//        Graphics2D g2 = (Graphics2D)g;

        int width = getWidth();
        int height = getHeight();
        Image backBuffer = createImage(width, height);
        Graphics2D g2 = (Graphics2D)(backBuffer.getGraphics());

        g2.setColor(Color.white);
        g2.fillRect(0, 0, width, height);

        g2.setColor(Color.black);

        if( map == null ){
            g2.drawString("NO MAP", getWidth()/2-20, getHeight()/2);
            return;
        }

        //draw horizontal lines
        for( int i = 0; i<=map.length; i++ ){
            g2.drawLine(20, i*(height-40)/map.length+20, width-20, i*(height-40)/map.length+20);
        }

        //draw vertical lines
        for( int i = 0; i<=map[0].length; i++ ){
            g2.drawLine(i*(width-40)/map[0].length+20, 20, i*(width-40)/map[0].length+20, height-20);
        }

        //draw each field
        for( int i = 0; i<map.length; i++ )
            for( int j = 0; j<map[i].length; j++){
                drawMarks(g2,
                        map[i][j],
                        i*(width-40)/map.length+21,
                        j*(height-40)/map[0].length+21,
                        (width-40)/map.length-2,
                        (height-40)/map[0].length-2
                        );
            }
        
        if( drawAgent )
            if( agentPosition!=null )
            {
                float alpha = 1.0f;
                if(map[agentPosition.x][agentPosition.y]!=0)
                    alpha = 0.7f;
                AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
                g2.setComposite(alphaComposite);
                g2.drawImage(imgKnight,
                        agentPosition.x*(width-40)/map.length+21,
                        agentPosition.y*(height-40)/map[0].length+21,
                        (width-40)/map.length-2,
                        (height-40)/map[0].length-2,
                        this
                        );
            }

        g.drawImage(backBuffer, 0, 0, this);
    }

    /**
     * repainting
     * @param g
     */
    @Override
    public void update(Graphics g){
        paint(g);
    }

    /**
     * Set new map to draw.
     * @param map new map
     * @return true if new map was accepted
     */
    public boolean setMap(int[][] map){
        if(map==null)
            return false;
        if( map.length <= 0 )
            return false;
        
        for( int i = 0; i<map.length; i++ )
            if( map[i].length != map.length )
                return false;
        
        this.map = map;
        return true;
    }

    /**
     * delete map (no map will be drawn)
     */
    public void resetMap(){
        map = null;
    }

    /**
     * enable/disable showing content of hidden fields
     * @param value
     */
    public void setRevealHidden(boolean value){
        revealHidden = value;
    }

    /**
     * draw content of single field
     * @param g device contekst which will be used to draw
     * @param state parameters of the field (content)
     * @param x position if the field on the canvas
     * @param y position if the field on the canvas
     * @param cx width of the fild
     * @param cy height of the field
     */
    public void drawMarks(Graphics2D g, int state, int x, int y, int cx, int cy){
        
        int count = 0;
        int drawn = 0;

        g.setBackground(Color.white);
        g.clearRect(x, y, cx, cy);
        
        if( ( state & HIDDEN ) != 0 && !revealHidden){
            g.drawImage(imgUnknown, x, y, cx, cy, this);
        } else {
            if( ( state & PIT ) != 0 ){
                g.drawImage(imgPit, x, y, cx, cy, this);
            } else {
                g.setColor(Color.white);

                if( ( state & ENTERENCE_LEFT ) != 0 )
                    g.fillRect(x-2, y, 2, cy);
                if( ( state & ENTERENCE_RIGHT ) != 0 )
                    g.fillRect(x+cx, y, 2, cy);
                if( ( state & ENTERENCE_UP ) != 0 )
                    g.fillRect(x, y-2, cx, 2);
                if( ( state & ENTERENCE_DOWN ) != 0 )
                    g.fillRect(x, y+cx, cx, 2);

                g.setColor(Color.black);
                
                if( ( state & WIND ) != 0 ){
                    count++;
                }
                if( ( state & SULFUR ) != 0 ){
                    count++;
                }

                if( ( state & WUMPUS ) != 0 ){
                    count++;
                }
                if( ( state & GOLD ) != 0 ){
                    count++;
                }
                if( ( state & CHEST ) != 0 ){
                    count++;
                }

                if(count == 2){
                    y+=cy/4;
                }

                if(count > 1){
                    cx/=2;
                    cy/=2;
                }

                if( ( state & WIND ) != 0 ){
                    g.drawImage(imgWind, x, y, cx, cy, this);
                    x+=cx;
                    drawn++;
                }
                if( ( state & SULFUR ) != 0 ){
                    g.drawImage(imgSulfur, x, y, cx, cy, this);
                    if(drawn == 1){
                        x-=cx;
                        y+=cy;
                    } else{
                        x+=cx;
                    }
                    drawn++;
                }

                if( ( state & WUMPUS ) != 0 ){
                    g.drawImage(imgBronzeDragon, x, y, cx, cy, this);
                    if(drawn == 1){
                        x-=cx;
                        y+=cy;
                    } else{
                        x+=cx;
                    }

                    drawn++;
                }
                if( ( state & GOLD ) != 0 ){
                    g.drawImage(imgGold, x, y, cx, cy, this);
                }
                if( ( state & CHEST ) != 0 ){
                    g.drawImage(imgChest, x, y, cx, cy, this);
                }
            }
        }
//
        if(showHints && doPrintHints){
            Color oldColor = g.getColor();
            Font oldFont = g.getFont();
            Composite oldComposite = g.getComposite();

            g.setColor(Color.LIGHT_GRAY);
            int offsetX = (int)(((getWidth()-40)/(2*map.length))/4);
            int offsetY = (int)(((getHeight()-40)/(2*map[0].length))/4);
            int round = offsetX*2;
            int fontSize= (int)( ((getHeight()-40)/map[0].length-2)/8 ) ;
            g.setFont(new Font("Arial",Font.BOLD,fontSize));

//            float alpha =0.5f;
//
//            AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
//            g.setComposite(alphaComposite);

//            g.fillRect( posX*(getWidth()-40)/map.length+21+offsetX, posY*(getHeight()-40)/map[0].length+21+offsetY, (getWidth()-40)/map.length-2-2*offsetX, (getHeight()-40)/map[0].length-2 - 2*offsetY);
            g.fillRoundRect( posX*(getWidth()-40)/map.length+21+offsetX,
                            posY*(getHeight()-40)/map[0].length+21+offsetY,
                            (getWidth()-40)/map.length-2-2*offsetX,
                            (getHeight()-40)/map[0].length-2-2*offsetY,
                             round,
                             round
                             );
            
            g.setColor(Color.RED);
            g.drawString(String.format("W: "+"%.1f"+"%%",noteW),
                    posX*(getWidth()-40)/map.length+21+offsetX*2,
                    posY*(getHeight()-40)/map[0].length+21+offsetY*4
                    );

            g.setColor(Color.BLUE);
            g.drawString(String.format("P: "+"%.1f"+"%%",noteP),
                    posX*(getWidth()-40)/map.length+21+offsetX*2,
                    posY*(getHeight()-40)/map[0].length+21+offsetY*6
                    );

            g.setColor(oldColor);
            g.setFont(oldFont);
            g.setComposite(oldComposite);
//            doPrintHints=false;
        }

    }

    void drawHint(int posX, int posY, float noteW, float noteP) {

        if(posX<0){
            this.doPrintHints=false; //mouse is not over the canvas - do not show hints
            this.repaint();
        }
        else{
            if(map[posX][posY]==(map[posX][posY] | MyCanvas.HIDDEN)){       //cell is hidden
                this.doPrintHints=true;
                this.posX=posX;
                this.posY=posY;
                this.noteW = noteW*100;
                this.noteP = noteP*100;
                this.repaint();
            }
            else{
                this.doPrintHints=false;
                this.repaint();
            }

        }

    }
}
